//
//  TargetType.swift
//  Network
//
//  Created by peiw on 2018/7/2.
//  Copyright © 2018年 Hiersun. All rights reserved.
//

import Foundation
import Moya
import Result
import SwiftyJSON

/// 服务器数据返回结果处理
public enum FxResponseResult<Value> {
    case success(Value)
    case failure(Error)
}
extension FxResponseResult {
    var value: Value? {
        switch self {
        case .success(let value):
            return value
        case .failure:
            return nil
        }
    }
    func map<R>(_ function: (Value) -> FxResponseResult<R>?) -> FxResponseResult<R> {
        switch self {
        case let .success(value):
            if let result = function(value) {
                switch result {
                case .success(let v):
                    return .success(v)
                case .failure(let error):
                    return .failure(error)
                }
            } else {
                return .failure(FxNetworkError.dataError(-1))
            }
        case let .failure(error):
            return .failure(error)
        }
    }
    func map<R>(_ function: (Value) -> R?) -> FxResponseResult<R> {
        switch self {
        case let .success(value):
            if let result = function(value) {
                return .success(result)
            } else {
                return .failure(FxNetworkError.dataError(-1))
            }
        case let .failure(error):
            return .failure(error)
        }
    }
    
    /// 执行function
    func apply(_ function: (FxResponseResult<Value>) throws -> Void) rethrows -> Void {
        switch self {
        case .success(let v):
            try function(.success(v))
        case .failure(let error):
            try function(.failure(error))
        }

    }
}

extension Result where T: Response {
    func fxFlatMap<R>(_ function: (T) -> R?) -> FxResponseResult<R> {
//        switch self {
//        case .success(let v):
////            let statusCode = v.statusCode
//            let data = v.data
//            if let json = JSON(data: data) {
//                return .success(json)
//            } else {
//                return .failure(FxNetworkError.dataError)
//            }
//        case .failure(let error):
//            return .failure(FxNetworkError.dataError)
//        }
        if let code = self.value?.statusCode {
            if code != 200 {
                return .failure(FxNetworkError.syserror(code))
            }
        }
        guard let v = value else {
            return .failure(FxNetworkError.dataError(-1))
        }
        guard let r = function(v) else {
            return .failure(FxNetworkError.dataError(-1))
        }
        return .success(r)
    }
}

public enum FxNetworkStatus {
    case none
    case wifi
    case wwan
}

/// 一般用来统一处理code异常情况，比如登录态失效
public typealias FxResponseHandler = (JSON) -> FxResponseResult<JSON>
public typealias FxRequestPreviousHandler = (FxNetworkStatus) -> Void
/// http请求协议
public protocol FxTargetType: TargetType {
    /// 是否使用本地模拟数据
    var useApiFixture: Bool { get }
    /// response处理
    var responseHandler: FxResponseHandler { get }
    var requestPreviousHandler: FxRequestPreviousHandler { get }
    var requestEndHandler: (Moya.Response?) -> Void { get }
}

